package pl.polidea.imf.blackberry.util;

import java.util.Vector;

import net.rim.device.api.applicationcontrol.ApplicationPermissions;
import net.rim.device.api.applicationcontrol.ApplicationPermissionsManager;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.CoverageInfo;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.GPRSInfo;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.SIMCardException;
import net.rim.device.api.system.SIMCardInfo;
import net.rim.device.api.system.WLANInfo;
import net.rim.device.api.system.WLANInfo.WLANAPInfo;
import net.rim.device.api.ui.component.Dialog;
import pl.polidea.imf.blackberry.ui.GlobalUIHelper;
import pl.polidea.imf.common.java.model.Condition;

public class DeviceStatusHelper {

	public static String getApplicationVersion() {
		String version = ApplicationDescriptor.currentApplicationDescriptor().getVersion();

		return version;

	}

	public static String getIMSI() {
		byte[] imsi = null;
		String res = "";
		try {
			imsi = SIMCardInfo.getIMSI();
		} catch (SIMCardException e) {
			/* ignore */

		}
		if (imsi != null) {
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < imsi.length; i++) {
				sb.append("" + imsi[i]);
			}
			res = sb.toString();
		}
		return res;
	}

	public static String getPhoneLanguage() {
		String lang = "";

		try {
			lang = System.getProperty("microedition.locale");
		} catch (Exception e) {

		}
		return lang;
	}

	public static long getMemoryFree() {
		long memory = -1;

		try {
			memory = Runtime.getRuntime().freeMemory();
		} catch (Exception e) {

		}
		return memory;
	}

	public static long getMemoryTotal() {
		long memory = -1;

		try {
			memory = Runtime.getRuntime().totalMemory();
		} catch (Exception e) {

		}
		return memory;
	}

	public static String getSystemName() {
		return "BlackBerry OS";
	}

	public static String getSystemVersion() {
		return DeviceInfo.getSoftwareVersion();

	}

	public String getDeviceManufacturer() {

		return DeviceInfo.getManufacturerName();
	}

	public String getDeviceName() {

		return DeviceInfo.getDeviceName();
	}

	public static int getBateryLevel() {
		return DeviceInfo.getBatteryLevel();
	}

	public static boolean isUsingExternalPower() {
		return ((DeviceInfo.getBatteryStatus() & DeviceInfo.BSTAT_IS_USING_EXTERNAL_POWER) == 0);
	}

	public static boolean isInRoaming() {
		return (0 != (RadioInfo.getState() & RadioInfo.NETWORK_SERVICE_ROAMING));
	}

	public static boolean isRadioOn() {
		return (0 != (RadioInfo.getState() & RadioInfo.STATE_ON));
	}

	public static boolean hasDataConnection() {
		return RadioInfo.isDataServiceOperational() || hasWIFI();
	}

	public static boolean has3G() {
		return RadioInfo.isDataServiceOperational();
	}

	public static boolean hasWIFI() {
		return (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED);
	}

	public static int getScreenHeight() {
		return Display.getHeight();
	}

	public static int getScreenWidth() {
		return Display.getWidth();
	}

	public static String getScreenOrientation() {
		String result = "";
//		switch (Display.getOrientation()) {
//			case Display.ORIENTATION_LANDSCAPE:
//				result = "landscape";
//				break;
//			case Display.ORIENTATION_PORTRAIT:
//				result = "portrait";
//				break;
//			case Display.ORIENTATION_SQUARE:
//				result = "square";
//				break;
//			default:
//				break;
//		}
		return result;
	}

	public static int getScreenNumberOfColors() {
		return Display.getNumColors();
	}

	public static String getWiFiSSID() {
		return WLANInfo.getAPInfo() == null ? null : WLANInfo.getAPInfo().getSSID();
	}

	public static String getWiFiBSSID() {
		return WLANInfo.getAPInfo() == null ? null : WLANInfo.getAPInfo().getBSSID();
	}

	public static int getWiFiDataRate() {
		return WLANInfo.getAPInfo() == null ? 0 : WLANInfo.getAPInfo().getDataRate();
	}

	public static int getWiFiSignalLevel() {
		return WLANInfo.getAPInfo() == null ? 0 : WLANInfo.getAPInfo().getSignalLevel();
	}

	public static String getWiFiBand() {
		WLANAPInfo info = WLANInfo.getAPInfo();
		String result = "";
		if (info == null) {
			return " ";

		}

		switch (info.getRadioBand()) {
			case WLANInfo.WLAN_BAND_A:
				result = "BAND_A";
				break;
			case WLANInfo.WLAN_BAND_B:
				result = "BAND_B";
				break;
			case WLANInfo.WLAN_BAND_BG:
				result = "BAND_BG";
				break;
			default:
				break;
		}

		return result;
	}

	public static String getTelephonyMediumType() {
		return "";
	}

	public static String getTelephonyNetworkType() {
		int networkType = RadioInfo.getNetworkType();
		String result = "";
		switch (networkType) {

			case RadioInfo.NETWORK_GPRS:
				result = "gprs";
				break;
			case RadioInfo.NETWORK_802_11:
				result = "802_11";
				break;
			case RadioInfo.NETWORK_UMTS:
				result = "umts";
				break;
			case RadioInfo.NETWORK_IDEN:
				result = "iden";
				break;
			case RadioInfo.NETWORK_CDMA:
				result = "cdma";
				break;
			default:
				break;
		}
		return result;
	}

	public static String getTelephonyIMEI() {
		return GPRSInfo.imeiToString(GPRSInfo.getIMEI(), false);
	}

	public static Object getValueForKey(String key) {
		Object result = null;

		if (key.equals(Condition.KEYS.BATERRY_LEVEL)) {
			result = new Integer(getBateryLevel());
		} else if (key.equals(Condition.KEYS.BATERRY_PLUGGED)) {
			result = new Boolean(isUsingExternalPower());

		} else if (key.equals(Condition.KEYS.SCREEN_HEIGHT)) {
			result = new Integer(getScreenHeight());

		} else if (key.equals(Condition.KEYS.SCREEN_WIDTH)) {
			result = new Integer(getScreenWidth());

		} else if (key.equals(Condition.KEYS.SCREEN_NUMBER_OF_COLORS)) {
			result = new Integer(getScreenNumberOfColors());

		} else if (key.equals(Condition.KEYS.SCREEN_ORIENTATION)) {
			result = getScreenOrientation();

		} else if (key.equals(Condition.KEYS.SYSTEM_FREE_MEMORY)) {
			result = new Long(getMemoryFree());

		} else if (key.equals(Condition.KEYS.SYSTEM_MAX_MEMORY)) {
			result = new Long(getMemoryTotal());

		} else if (key.equals(Condition.KEYS.SYSTEM_LOCALE)) {
			result = getPhoneLanguage();

		} else if (key.equals(Condition.KEYS.SYSTEM_OS_NAME)) {
			result = getSystemName();

		} else if (key.equals(Condition.KEYS.SYSTEM_OS_VERSION)) {
			result = getSystemVersion();

		} else if (key.equals(Condition.KEYS.TELEPHONY_DEVICE_ID)) {
			result = getTelephonyIMEI();

		} else if (key.equals(Condition.KEYS.TELEPHONY_IMSI)) {
			result = getIMSI();

		} else if (key.equals(Condition.KEYS.TELEPHONY_MEDIUM_TYPE)) {
			result = getTelephonyMediumType();

		} else if (key.equals(Condition.KEYS.TELEPHONY_NETWORK_TYPE)) {
			result = getTelephonyNetworkType();

		} else if (key.equals(Condition.KEYS.TELEPHONY_ROAMING)) {
			result = new Boolean(isInRoaming());

		}
		else if (key.equals(Condition.KEYS.WIFI_RADIO_BAND)) {
			result = getWiFiBand();

		}
		else if (key.equals(Condition.KEYS.WIFI_RADIO_BSSID)) {
			result = getWiFiBSSID();

		}
		else if (key.equals(Condition.KEYS.WIFI_RADIO_DATA_RATE)) {
			result = new Integer(getWiFiDataRate());

		}
		else if (key.equals(Condition.KEYS.WIFI_RADIO_SSID)) {
			result = getWiFiSSID();
		}
		else if (key.equals(Condition.KEYS.WIFI_RADIO_STATE)) {
			result = "unimplemented";
		}
		else if (key.equals(Condition.KEYS.WIFI_SIGNAL_LEVEL)) {
			result = new Integer(getWiFiSignalLevel());
		}

		return result;
	}

	public static Vector getValidConnectionsAppendix(boolean useWiFi, boolean use3G) {
		Vector result = new Vector();
		if (hasWIFI() && useWiFi) {
			result.addElement(";interface=wifi");
		} else if (has3G() && use3G) {
			ServiceRecord srMDS = null, srWAP2 = null;
			ServiceRecord srBIS = null;
			ServiceBook sb = ServiceBook.getSB();
			ServiceRecord[] records = sb.getRecords();

			for (int i = 0; i < records.length; i++) {
				ServiceRecord myRecord = records[i];
				String cid, uid;

				if (myRecord.isValid() && !myRecord.isDisabled()) {
					cid = myRecord.getCid().toLowerCase();
					uid = myRecord.getUid().toLowerCase();

					// BIS
					if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") != -1) {
						srBIS = myRecord;
					}

					// BES
					if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") == -1) {
						srMDS = myRecord;
					}

					// Wap2.0
					if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") == -1 && uid.indexOf("mms") == -1) {
						srWAP2 = myRecord;
					}
				}
			}

			if (srWAP2 != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT)) {
				result.addElement(";deviceside=true" + ";ConnectionUID=" + srWAP2.getUid());
			} else if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT)) {
				result.addElement(";deviceside=true");
			}

			else if (srBIS != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) {
				result.addElement(";deviceside=false;ConnectionTimeout=30000");
			} else if (srMDS != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS)) {
				result.addElement(";deviceside=false;ConnectionTimeout=30000");
			}
		}
		result.addElement("");
		return result;
	}

	public static boolean checkPermissionsAndAsk() {

		if (checkPermissions()) {
			return true;
		}

		ApplicationPermissions perm = ApplicationPermissionsManager.getInstance().getApplicationPermissions();

		if (perm.getPermission(ApplicationPermissions.PERMISSION_FILE_API) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_FILE_API);
		}
		if (perm.getPermission(ApplicationPermissions.PERMISSION_INTERNET) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_INTERNET);
		}
		if (perm.getPermission(ApplicationPermissions.PERMISSION_MEDIA) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_MEDIA);
		}
		if (perm.getPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA);
		}
		if (perm.getPermission(ApplicationPermissions.PERMISSION_PHONE) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_PHONE);
		}

		if (perm.getPermission(ApplicationPermissions.PERMISSION_WIFI) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_WIFI);
		}
		if (perm.getPermission(ApplicationPermissions.PERMISSION_INPUT_SIMULATION) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_INPUT_SIMULATION);
		}
		if (perm.getPermission(ApplicationPermissions.PERMISSION_RECORDING) != ApplicationPermissions.VALUE_ALLOW) {
			perm.addPermission(ApplicationPermissions.PERMISSION_RECORDING);
		}
		if (ApplicationPermissionsManager.getInstance().invokePermissionsRequest(perm)) {
			return true;
		} else {
			Dialog dialog = new Dialog(Dialog.D_OK, "Insuffitient permission imf may not work correctly!", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION), Dialog.VERTICAL_SCROLL);
			GlobalUIHelper.pushGlobalScreen(dialog);
			return false;

		}

	}

	public static boolean checkPermissions() {

		ApplicationPermissions perm = ApplicationPermissionsManager.getInstance().getApplicationPermissions();
		boolean isAllowed = true;
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_FILE_API) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_INTERNET) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_MEDIA) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_PHONE) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_INPUT_SIMULATION) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_WIFI) == ApplicationPermissions.VALUE_ALLOW);
		isAllowed = isAllowed && (perm.getPermission(ApplicationPermissions.PERMISSION_RECORDING) == ApplicationPermissions.VALUE_ALLOW);

		return isAllowed;
	}

}
